
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Kafka的分区机制 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>Kafka的分区机制 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">在 Kafka 中，Partition 是什么？它有哪些核心特性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Partition 是 Kafka 消息系统的基本单元。每个 Topic 可以拥有多个 Partition。其核心特性是：每个分区都是一个日志文件，写入的消息会按顺序排列，并且每条消息都有一个唯一的 Offset。</div>
          </div>
          <div class="card-source">来源: 1. Kafka 分区概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Kafka 生产者在发送消息时，是如何决定将消息发送到哪个分区的？请描述有 Key 和无 Key 两种情况。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">生产者根据 Partitioner 规则来决定分区。如果消息有 Key，则根据消息 Key 的哈希值来选择分区，确保相同 Key 的消息进入同一分区。如果消息没有 Key，Kafka 会采取轮询的方式将消息均匀地分配到各个分区。</div>
          </div>
          <div class="card-source">来源: 3. 消息生产者如何选择分区</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">为什么在 Kafka 中使用消息 Key 发送消息可以保证消息的顺序性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为 Kafka 的分区器确保具有相同 Key 的消息始终被路由到同一个 Partition 中。由于在单个 Partition 内消息是有序的，因此这保证了这些具有相同 Key 的消息的顺序性。</div>
          </div>
          <div class="card-source">来源: 3. 消息生产者如何选择分区</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 Kafka 的副本机制中，'Leader' 和 'Follower' 副本分别扮演什么角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">'Leader' 副本负责处理其所在分区的所有读写请求。'Follower' 副本则不直接处理请求，它们的主要任务是从 'Leader' 副本获取最新的数据并进行同步，以作为备份。</div>
          </div>
          <div class="card-source">来源: 5. Partition 副本机制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">概念</div>
          <div class="card-question">Kafka 中的 ISR (In-Sync Replicas) 是什么？它在容错机制中有什么作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">概念</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ISR 指的是“同步副本集合”（In-Sync Replicas）。它用来管理哪些副本与 Leader 副本的数据是保持同步的。只有处于 ISR 中的副本才被认为是有效副本，并且在 Leader 节点失效时有资格被选举为新的 Leader。</div>
          </div>
          <div class="card-source">来源: 5. Partition 副本机制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当一个 Partition 的 Leader 节点失效时，Kafka 会如何进行故障恢复？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当 Leader 节点失效时，Kafka 会触发 Leader 选举机制。它会从 ISR（同步副本集合）中选择一个新的副本作为新的 Leader。这个过程由 Zookeeper 协调，以确保集群能够快速恢复并继续提供服务。</div>
          </div>
          <div class="card-source">来源: 7. 分区的故障恢复与领导者选举</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">消费者组（Consumer Group）内的消费者是如何消费 Topic 中的分区的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在消费者组中，每个消费者会被分配消费一个或多个特定的 Partition。消费者只会从自己被分配到的 Partition 中按 Offset 顺序读取消息，从而实现并发消费和负载均衡。</div>
          </div>
          <div class="card-source">来源: 4. 消费者如何读取分区数据</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">Kafka 的分区机制如何支持系统的水平扩展和高吞吐量？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过将一个 Topic 分成多个 Partition，Kafka 可以在多个 Broker 机器上并行地分发、存储和处理消息。这种并行处理能力极大地提升了系统的吞吐量和水平扩展能力。</div>
          </div>
          <div class="card-source">来源: 1. Kafka 分区概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">为一个已存在的 Topic 增加分区数量可能带来什么潜在问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">虽然 Kafka 支持动态增加分区数量以提升扩展性，但这会导致已有的数据进行重新平衡（rebalance），这个过程可能会影响系统的实时性能，因此增加分区通常需要谨慎操作。</div>
          </div>
          <div class="card-source">来源: 8. 分区的扩展性</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
